package pl.grabar.clinic.core.dao.db;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;

import pl.grabar.clinic.core.dao.Dao;
import pl.grabar.clinic.core.dao.EntityManagerFactoryService;
import pl.grabar.clinic.core.domain.person.Doctor;

public class DoctorDataBaseDao implements Dao<Doctor> {

	private static final Log LOG = LogFactory.getLog(DoctorDataBaseDao.class);

	@Autowired
	private EntityManagerFactoryService entityManagerFactory;

	private EntityManager entityManager;

	public void init() {
		this.entityManager = entityManagerFactory.getEntityManag();
	}

	@Override
	public Doctor findById(Serializable id) throws SQLException {
		Doctor user = null;
		try {
			entityManager.getTransaction().begin();
			user = entityManager.find(Doctor.class, Long.parseLong((String) id));
			entityManager.getTransaction().commit();
		} catch (Exception e) {
			entityManager.getTransaction().rollback();
			e.printStackTrace();
			LOG.info(e.getMessage());
			LOG.debug("DEBUG: ", e);
		}
		return user;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Doctor> findAll() throws SQLException {
		List<Doctor> listUsers = new ArrayList<>();
		try {
			entityManager.getTransaction().begin();
			Query query = entityManager.createQuery("select k from Doctor k");
			listUsers = (ArrayList<Doctor>) query.getResultList();
			entityManager.getTransaction().commit();
		} catch (Exception e) {
			entityManager.getTransaction().rollback();
			e.printStackTrace();
			LOG.info(e.getMessage());
			LOG.debug("DEBUG: ", e);
		}
		return listUsers;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Doctor> findAll(Integer pageNumber, Integer pageSize, String sortProperty, String sortOrder) throws SQLException {
		List<Doctor> listUsers = new ArrayList<>();
		try {
			entityManager.getTransaction().begin();
			Query query = entityManager.createQuery("select k from Doctor k");
			listUsers = (ArrayList<Doctor>) query.getResultList();
			entityManager.getTransaction().commit();
		} catch (Exception e) {
			entityManager.getTransaction().rollback();
			e.printStackTrace();
			LOG.info(e.getMessage());
			LOG.debug("DEBUG: ", e);
		}
		return listUsers;
	}

	@Override
	public List<Doctor> findAll(Integer pageNumber, Integer pageSize, String sortProperty, String sortOrder, Map<String, String> filter) throws SQLException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Long countAll() throws SQLException {
		Long cResults = 0l;
		try {
			entityManager.getTransaction().begin();
			Query query=entityManager.createQuery("SELECT COUNT(*) FROM Doctor p");
			cResults=(Long) query.getSingleResult();
			entityManager.getTransaction().commit();
		} catch (Exception e) {
			entityManager.getTransaction().rollback();
			LOG.info(e.getMessage());
			LOG.debug("DEBUG: ", e);
		}		
		return cResults;
	}

	@Override
	public Long countAll(Map<String, String> filter) throws SQLException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void save(Doctor objectToSave) throws SQLException {
		try {
			entityManager.getTransaction().begin();
			entityManager.persist(objectToSave);
			entityManager.getTransaction().commit();
		} catch (Exception e) {
			entityManager.getTransaction().rollback();
			LOG.info(e.getMessage());
			LOG.debug("DEBUG: ", e);
		}
	}

	@Override
	public void update(Doctor transientObject) throws SQLException {
		try {
			entityManager.getTransaction().begin();
			Doctor user = entityManager.find(Doctor.class, transientObject.getId());
			user = transientObject;
			entityManager.merge(user);
			entityManager.getTransaction().commit();
		} catch (Exception e) {
			entityManager.getTransaction().rollback();
			LOG.info(e.getMessage());
			LOG.debug("DEBUG: ", e);
		}
	}

	@Override
	public void delete(Doctor transientObject) throws SQLException {
		try {
			entityManager.getTransaction().begin();
			entityManager.remove(transientObject);
			entityManager.getTransaction().commit();
		} catch (Exception e) {
			entityManager.getTransaction().rollback();
			LOG.info(e.getMessage());
			LOG.debug("DEBUG: ", e);
		}
	}

	public EntityManagerFactoryService getEntityManagerFactory() {
		return entityManagerFactory;
	}

	public void setEntityManagerFactory(EntityManagerFactoryService entityManagerFactory) {
		this.entityManagerFactory = entityManagerFactory;
	}

}
